package edu.neumont.csc380.prime.service;

import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Random;

import javax.ws.rs.Path;

import org.springframework.stereotype.Service;

@Service
@Path("/prime")
public class ProbablyPrimeService implements PrimeClientServerAPI{
	static final String baseUrl = "http://localhost:8080/InYourPrime/rest/prime/";
		
	public ProbablePrime getProbablePrimeJSON(){
		BigInteger rand = new BigInteger(31,new Random());
		ProbablePrime pp = new ProbablePrime(rand.intValue(), new Witnesses());
		pp.setRecall(baseUrl+pp.getNumber()+"/");
		return fermatTest(pp);
	}

	public ProbablePrime getProbablePrimeXML(){
		BigInteger rand = new BigInteger(31,new Random());
		ProbablePrime pp = new ProbablePrime(rand.intValue(), new Witnesses());
		pp.setRecall(baseUrl+pp.getNumber()+"/");
		return fermatTest(pp);
	}
	
	public ProbablePrime getProbablePrimeJSON(int number, String witnesses){
		String[] temp = witnesses.split(",");
		int[] witnessesArray = new int[temp.length];
		for(int i = 0; i < temp.length; i++)
			witnessesArray[i]=Integer.parseInt(temp[i]);
			
		ProbablePrime pp = new ProbablePrime(number,new Witnesses(witnessesArray));
		String recall = baseUrl+pp.getNumber()+"/";
		for(int w: witnessesArray)
			recall+=w+",";
		recall = recall.substring(0,recall.length()-1);
		pp.setRecall(recall);
		
		return fermatTest(pp);
	}
	
	public ProbablePrime getProbablePrimeXML(int number, String witnesses){
		String[] temp = witnesses.split(",");
		int[] witnessesArray = new int[temp.length];
		for(int i = 0; i < temp.length; i++)
			witnessesArray[i]=Integer.parseInt(temp[i]);
		
		ProbablePrime pp = new ProbablePrime(number,new Witnesses(witnessesArray));
		String recall = baseUrl+pp.getNumber()+"/";
		for(int w: witnessesArray)
			recall+=w+",";
		recall = recall.substring(0,recall.length()-1);
		pp.setRecall(recall);
		
		return fermatTest(pp);
	}
	private ProbablePrime fermatTest(ProbablePrime probablePrime){//should possibly check the random number against the witnesses, if already a witness gen new random number
		//loop k time
		int k = 10000;
		for(int i = 0; i < k; i++){
			Random random = new Random();
			int n = probablePrime.getNumber();
			int a;
			do{
				a = random.nextInt((int) (n-1))+2;
			}while(probablePrime.getWitnesses().getWitnesses().contains(a));
			
			//System.out.println("A: " + a + "\nN: " + n + "\nMOD: " + a%n);
			if(a%n == 1){//Composite, break loop
				probablePrime.setConfidence(0);
				probablePrime.setRecall("The number is composite");
				return probablePrime;
			}
			probablePrime.getWitnesses().getWitnesses().add(a);
//			ncr.setWitnesses(ncr.getWitnesses() + "," + a);
//			ncr.setNumWitnesses(ncr.getNumWitnesses()+1);
		}
//		end loop
		
		float c = (float)probablePrime.getWitnesses().getWitnesses().size()/(float)probablePrime.getNumber();
		//System.out.println(c);
		probablePrime.setConfidence(c);
		
		if(probablePrime.getRecall().endsWith("/"))
			probablePrime.setRecall(probablePrime.getRecall()+probablePrime.getWitnesses().toString());
		else probablePrime.setRecall(probablePrime.getRecall()+","+probablePrime.getWitnesses().toString());
		return probablePrime;
	}
}
